package soo;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

/**
 * 数字验证码识别器（用于识别xxx系统的图片验证码）
 * 
 * 算法如下： 分析验证码图片结构，将其分隔成4个独立的数字图片，把四个独立的数字图片处理成单色位图。
 * 把单色位图转换为0、1数组，然后分别和0-9的字模进行匹配，得到图片上的数字信息。
 * 
 * @since JDK 1.5.0_8
 */
public class NumberVerCodeIdentifier3 {
	public static char[][] chararray= new char[9][96];

	static {
		System.setProperty("com.sun.media.jai.disableMediaLib", "true");

		String a0 = "001111000111111011100111110000111100001111000011110000111100001111000011111001110111111000111100";
		String a1 = "000011000001110000111100011011000100110000001100000011000000110000001100000011000000110000001100";
		String a2 = "001111000111111011100011110000110000001100000110000011100001110000111000011000001111111111111111";
		String a3 = "001111100111111111000011000000110001111000011110000001110000001111000011111001110111111000111100";
		String a4 = "000001100000111000001110000111100011011000110110011001101100011011111111111111110000011000000110";
		String a5 = "011111100111111001100000111000001111110011111110110001110000001111000011111001110111111000111100";
		String a6 = "001111100111111101100011110000001101110011111110111001111100001111000011011000110111111000111100";
		String a7 = "111111111111111100000110000011000000110000011000000110000001100000111000001100000011000000110000";
		String a8 = "001111000111111011000011110000111100001101111110011111101100001111000011110000110111111000111100";
		chararray[0] =a0.toCharArray();
		chararray[1] =a1.toCharArray();
		chararray[2] =a2.toCharArray();
		chararray[3] =a3.toCharArray();
		chararray[4] =a4.toCharArray();
		chararray[5] =a5.toCharArray();
		chararray[6] =a6.toCharArray();
		chararray[7] =a7.toCharArray();
		chararray[8] =a8.toCharArray();

	}


	
	
	
	
	public int recognize(BufferedImage image) {

		int result = 0;

		BufferedImage newim[] = new BufferedImage[2];
		if (null == image) {
			throw new RuntimeException("iamage为null");
		}
		// 将图像分成2块，因为要处理的文件有2个数字。

		newim[0] = generateSingleColorBitMap(image.getSubimage(0, 5, 8, 12),
				"a");

		newim[1] = generateSingleColorBitMap(image.getSubimage(26, 5, 8, 12),
				"b");

		for (int k = 0; k < 2; k++) {
			int iw = newim[k].getWidth(null);
			int ih = newim[k].getHeight(null);

			StringBuffer numstr = new StringBuffer();
			// 因为是二值图像，这里的方法将像素读取出来的同时，转换为0，1的图像数组。

			for (int i = 0; i < ih; i++) {
				for (int j = 0; j < iw; j++) {

					int t = newim[k].getRGB(j, i);
					if (t == -1)
						numstr.append("0");
					else
						numstr.append("1");

				}
			}
			// 得到像匹配的数字串。
			String aaaaa = numstr.toString();
			result = result + maxSame(aaaaa);
		}
		// System.out.println(result);
		return result;

	}

	public int maxSame(String result) {
		int[] sames = new int[9];

		char[] target = result.toCharArray();

		for (int i = 0; i < 8 * 12; i++) {
			
			for(int j=0; j<=8;j++){
				if (target[i] == chararray[j][i]) {
					sames[j]++;
				}
			}
		}

		int resultStr = 0;
		int max = 0;
		for (int i = 0; i <= 8; i++) {
			if (max < sames[i]) {
				max = sames[i];
				resultStr = i;
			}

		}

		return resultStr ;
	}

	/**
	 * 单色位图转换
	 * 
	 * @return
	 */
	private static BufferedImage generateSingleColorBitMap(Image colorImage,
			String tempFile) {
		BufferedImage image = new BufferedImage(8, 12,
				BufferedImage.TYPE_BYTE_GRAY);
		Graphics g = image.getGraphics();
		g.drawImage(colorImage, 0, 0, null);
		g.dispose();
		RenderedOp ro = JAI.create("binarize", image, new Double(100));
		BufferedImage bi = ro.getAsBufferedImage();

		File file = new File("/home/jeffrey/Downloads/img/" + tempFile);
		String format = "JPEG";
		try {
			ImageIO.write(image, format, file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}// 将图片保存为jpeg格式的文件file。也可以保存为jpg格式
		file = new File("/home/jeffrey/Downloads/img/" + tempFile + tempFile);
		try {
			ImageIO.write(bi, format, file);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}// 将图片保存为jpeg格式的文件file。也可以保存为jpg格式

		return bi;
	}

	/**
	 * 测试
	 */
	public static void main(String args[]) {

		NumberVerCodeIdentifier3 nvi = new NumberVerCodeIdentifier3();

		int res = 0;
		try {
			res = nvi.recognize(ImageIO.read(new File(
					"/home/jeffrey/Downloads/img/12.jpeg")));

			// res = nvi.recognize(ImageIO.read(new
			// URL("http://******.com/validationCode.jsp")));
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(res);
	}
}